package xserver;

import org.apache.mina.common.IoHandlerAdapter;
import org.apache.mina.common.IoSession;

import xgame.AbstractXcommand;
import xgame.AbstractXhandler;
import xgame.IXoutput;
import xgame.IXsession;

/**
 * 自定义 IO 处理器
 *  
 * @author AfritXia
 * @version $Rev: 17 $
 *
 */
final class MyIoHandler extends IoHandlerAdapter {
	@Override
	public void sessionCreated(IoSession session) {
		if (session == null) {
			return;
		}

		// 创建会话 Id
		long sessionId = System.currentTimeMillis();

		// 设置会话 Id
		session.setAttribute(XgameSession.SESSION_ID, sessionId);

		// 添加游戏会话到管理器
		XgameSessionManager.putGameSession(sessionId, new XgameSession(session));
	}

	@Override
	public void messageReceived(IoSession session, Object message) {
		if (session == null || message == null) {
			return;
		}

		// 获取会话 Id
		long sessionId = (Long)session.getAttribute(XgameSession.SESSION_ID);
			
		// 命令对象
		AbstractXcommand cmd = (AbstractXcommand)message;
		// 命令处理器
		AbstractXhandler<? extends AbstractXcommand> h = XmoduleTManager.getHandler(cmd.getId());

		if (h != null) {
			// 创建设置器
			MyXhandlerSetter setter = new MyXhandlerSetter(h);

			// 设置命令
			setter.setCommand(cmd);
			// 设置会话
			setter.setSession(XgameSessionManager.getGameSession(sessionId));
			// 设置输出对象
			setter.setOutput(new XgameOutput(session));

			// 处理命令对象
			h.handle();
		} else {
			System.out.println("cmdHandler is null");
		}
	}

	/**
	 * 自定义处理器设置者
	 * 
	 * @author AfritXia
	 * @version $Rev: 17 $
	 *
	 */
	private static class MyXhandlerSetter extends AbstractXhandler.Friend {
		/**
		 * 处理器
		 * 
		 */
		private AbstractXhandler<? extends AbstractXcommand> _h = null;
		
		/**
		 * 类参数构造器
		 * 
		 * @param h
		 * @throws IllegalArgumentException if h == null 
		 * 
		 */
		public MyXhandlerSetter(AbstractXhandler<? extends AbstractXcommand> h) {
			if (h == null) {
				throw new IllegalArgumentException("h is null");
			}

			this._h = h;
		}

		/**
		 * 设置命令对象
		 * 
		 * @param value 
		 * 
		 */
		public void setCommand(AbstractXcommand value) {
			super.setAbstractCommand(this._h, value);
		}

		/**
		 * 设置会话
		 * 
		 * @param value 
		 * 
		 */
		public void setSession(IXsession value) {
			super.setSession(this._h, value);
		}

		/**
		 * 设置输出对象
		 * 
		 * @param value 
		 * 
		 */
		public void setOutput(IXoutput value) {
			super.setOutput(this._h, value);
		}
	}
}
